This patch adds decoding for Opus, FLAC, and MP3 compressed audio tracks; up from the existing Vorbis decoding which DOSBox currently supports.

This top-level post will include:

    The latest patch and builds for Windows, Linux, and macOSX
    Links to the latest encoders
    Suggested compression settings to get the most compression-bang-for-your-bytes
    Example CUE files for these new codecs
    Technical discussion of runtime and source improvements


1. Why should we care? or Ogg Vorbis ought to be enough for anybody!

    All gamers, archivists, and collectors should reap the benefits these codecs offer in DOSBox
    Opus and FLAC, by the Xiph organization, are currently best-in-class open-licensed codecs, covering the range of lossy to lossless compression. Vorbis and Speex are deprecated.
    Opus has consistently beaten AAC, High-Efficiency-AAC (HE-AAC), Vorbis+Speex, and MP3 in objective ABX-based listening tests
    FLAC typically reduces a WAVs filesize by 50% to 70%, and in some cases up to 80% to maximize lossless space savings
    CPU usage to decode these (instead of Vorbis and WAV) is unchanged, so there are only gains here - we're not trading off anything


When it comes to handling audio content from the golden-era of PC gaming, these games deserve the best we can offer.

2. What's the goal of this patch?

    I want to work with the core developers to add these codecs to the core DOSBox source, in whatever final form is best for maintainability and the developers
    This isn't about me - it's about bringing quality audio codecs to DOSBox so everyone can use FLAC and Opus tracks


3. How will this playout given GOG uses Vorbis; isn't this patch unecessary?

    Those existing GOG releases will continue to work just fine
    When the stable release of DOSBox supports Opus and FLAC, I suspect GOG will deprecate Vorbis
    Users ripping their own CDROMs or BIN/CUE pairs will be able to go straight to FLAC or Opus, and not use Vorbis (which is inferior) or WAV (which is space-wasting)
    Enterprising users who care about audio quality might re-rip their existing collections


4. I've ripped my CDCROM and have a bunch of WAV files ready to compress - where can I get the latest codec compressors?

Opus 1.3:

    Windows 32bit: https://archive.mozilla.org/pub/opus/wi ... us-1.3.zip
    Windows 64bit: https://archive.mozilla.org/pub/opus/wi ... -win64.zip
    macOSX: brew install opus-tools (if you don't have brew, see: http://macappstore.org/opus-tools/)
    Linux: apt/zypper/yum install opus-tools (or build from source: ogg, opus, libopusfile, and opus-tools)


FLAC 1.3.2:

    Windows: https://ftp.osuosl.org/pub/xiph/release ... .2-win.zip
    macOSX: brew install flac (if you don't have brew, see: http://macappstore.org/flac/)
    Linux: apt/zypper/yum install flac (or build from source, http://www.linuxfromscratch.org/blfs/vi ... /flac.html)


Vorbis 1.4:

    Windows: http://downloads.xiph.org/releases/vorb ... -1.4.0.zip
    macOSX: brew install flac (if you don't have brew, see: http://macappstore.org/vorbis-tools/)
    Linux: apt/zypper/yum install vorbis-tools (or build from source, http://www.linuxfromscratch.org/blfs/vi ... tools.html)


LAME 3.100:

    Windows: http://www.rarewares.org/mp3-lame-bundle.php
    macOSX: brew install lame (if you don't have brew, see: http://macappstore.org/lame/)
    Linux: apt/zypper/yum install lame (or build from source, http://www.linuxfromscratch.org/blfs/vi ... /lame.html)


5. What are some recommended settings I can try?

FLAC (all files):

    flac -8 -e -p -b 512 -P=4096 -S- --output-name="outfile" "wavfile", followed by
    metaflac --add-seekpoint=1s "flacfile"

Opus, for mono voice-only tracks:

    opusenc --speech --bitrate 24 --downmix-mono "wavfile" "outfile"
    Alone in the Dark 2, tracks 23 to 63
    Alone in the Dark 3, tracks 24 to 61
    Battle Chess Enhanced, track 22
    Big Red Racing, tracks 12 to 29, and 33 to 39
    Jones in the Fast Lane: all tracks
    Shadowcaster: all tracks

Opus, for stereo voice-only tracks:

    opusenc --speech --bitrate 36 "wavfile" "outfile"
    Action Soccer, tracks 2 to 13
    AD&D Dark Sun II Wake of the Ravager, tracks 38 and 39
    Loom: all tracks

Opus for mono non-voice tracks:

    opusenc --bitrate 54 --downmix-mono "wavfile" "outfile"
    Destruction Derby, tracks 2, and 4 to 9
    Stellar 7, tracks 4 and 5
    Zyclunt, all tracks

Opus for stereo non-voice tracks:

    opusenc --bitrate 84 "wavfile" "outfile"


6. How should my CUE files look?

Here's a CUE with examples for each codec:

Code: Select all
    FILE "data.iso" BINARY
      TRACK 01 MODE1/2048
        INDEX 01 00:00:00

    FILE "track02.opus" OPUS
      TRACK 02  AUDIO
        PREGAP 00:02:00
        INDEX 01 00:00:00

    FILE "track03.flac" FLAC
      TRACK 03 AUDIO
        INDEX 01 00:00:00
       
    FILE "track04.ogg" OGG
      TRACK 04 AUDIO
        INDEX 01 00:00:00

    FILE "track05.mp3" MP3
      TRACK 05 AUDIO
        INDEX 01 00:00:00



7. What runtime improvements have been made?

    Replaces the existing audio callback routine with an efficient chunked circular-buffer audio reader
    Replaces assumptions that all audio tracks are 44.1 kHz & stereo. The mixer is now fed data at the actual compressed track's rate and channel count
    Eliminates all SDL locks in the audio code in favour of mixer state control
    Fixes the CDROM double-load bug (https://sourceforge.net/p/dosbox/bugs/488/), now using ripsaw8080's one-line preemptive fix
    Queries the codec for track-length instead of using hundreds of iterative decimating seeks to determine track length (loading a 99-track CUE now takes 0.1 user-seconds versus 3+ seconds previously)
    Adds handling for exact track positions via MSF values if specified in the cue file (https://sourceforge.net/p/dosbox/bugs/489/)
    The Opus decoder seek within its buffer (if possible) before actually moving the file pointer and re-running the decode sequence to get a different chunk of data; an optimization not found in the other codecs
    SDL_Sound's buffer-size is now set once and never resized, which eliminates repeated re-malloc'ing in the library
    Only one seek is performed per-playback sequence followed by sequential decodes, similar to a physical CDROM (current code reads 2352-byte chunks and includes seek calculations for every read)
    The DOSBox mixer channel is now only active during playback sequences, and is no longer left active and fed with silence, which reduce call overhead and audio latency in the mixer
    When using Opus audio tracks, and if your dosbox-SVN.conf [mixer] rate=48000, then you will (very likely) achieve sample-exact unadulterated pass-through along your entire audio chain from the decoder, to DOSBox, to your operating system's software mixer, to your sound card driver, to your sound card, to your speakers, or to your digital receiver / USB speakers/headphones / or HDMI TV/screen. This is because almost all modern hardware DACs use a native sample rate of 48000


8. What source-level maintenance improvements have been made?

    Eliminated external dependence on SDL_Sound and its mess of external library dependencies -- thank you Dominus and DosFreak for recommending this approach.
    SDL_Sound, Vorbis, FLAC, Opus, and Ogg libraries are not needed on your system nor do you need to build or provide pointers to these in CFLAGS/LIBS/etc..
    All codec handling is 100% internal DOSBox's to source and "always on"
    It strips all references to SDL_Sound from configure.ac
    It strips all pre-processor #ifdef branching for SDL_Sound from the code
    For Vorbis decoding, we now use the single-header stb_vorbis.h instead of of libogg, libvorbis, and libvorbisfile
    For MP3 decoding, we now use the single-header dr_mp3.h instead of libmp123
    For FLAC decoding, we now use the single-header dr_flac.h instead of libogg and libFLAC
    It adds src/libs/decoders, which holds the top-level opus, flac, vorbis, and wav decoders
    It adds src/libs/decoders/internal, where the opus-dependencies are automatically fetched, built, and linked as part of DOSBox's internal libraries
    Fixes all codec compiler warnings; 100% clean builds now
    Build-tested on Linux, MacOSX (xcode), and Windows (MinGW msys 1.0)


The Makefile in src/libs/decoders/internal fetches Opus's dependencies using curl, so that should be in your PATH.

    If you're on MinGW MSYS 1.0, I would suggest installing Git For Windows and allowing it to add itself to your PATH, which gives you a modern curl build
    If you're on MinGW-32/64 or MSYS 2.0, then you might already have curl or can use their package manager to install it
    macOS and Linux come with curl, so no action needed


9. What about SDL_Sound 1.0.3, can't we sit back and wait for the SDL Developers to add Opus and fix its broken MP3 and FLAC decoding?

SDL Sound 1.0.3 hasn't been touched in over a decade and has many bugs and autotool issues within modern environments. The developers are unyeilding on going back and fixing SDL1 libraries to accomodate issues cropping up in modern environments. For them, it's SDL2 or the highway. Example: https://forums.libsdl.org/viewtopic.php?p=45264 (that was 4 years ago, and we're still at SDL 1.2.15)

Ryan Gordon informed me he will use my Opus decoder to add Opus handling to this new SDL2-based sound libraries, however DOSBox would have to move to SDL2 to get it.

This patch brings audio-codec handling under our own control, strips it down to the bare minimum, and corrects all deficiencies.

If and when DOSBox decides to move to SDL2, we can decide then if we want to move back to dependence on SDL2_Sound.